﻿namespace Example
{
    using INCerry.IOC;
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            // 获取IOC容器
            var ioc = IOCContainer.GetInstance();

            #region 1.绑定接口与获取实例
            //// 可以通过泛型，类Type，命名空间字符串等方式绑定
            //// 实例创建模式为单例
            ////ioc.Bind<IFly, Bird>()
            ////    .SetCreationMethod<IFly>(CreateObjectMode.Singleton);

            //// 通过字符串的形式绑定  格式为 程序集名,完整的类名 
            //// 如果程序集在同一文件夹下，将会自动加载
            //ioc.Bind("Example,Example.IFly", "Example,Example.Bird")
            //    .SetCreationMethod("Example,Example.IFly", CreateObjectMode.Singleton);

            //// 2.获取类型实例 - 无参
            //IFly fly = ioc.Get<IFly>();
            //fly.ICanFly(); 
            #endregion

            #region 2.构造函数注入
            //// 绑定引擎 和 汽车
            //ioc.Bind<IEngine, V8Engine>();
            //ioc.Bind<ICar, AMGS63>();

            //// 获取汽车实例 由于汽车没有无参构造函数 
            //// IOC容器会自动查找 是否有已存在的类型实例
            //// 实现构造函数注入
            //ICar car = ioc.Get<ICar>();
            //car.ShowCarInfo();

            //// 也可以自行指定 实参
            //ICar car2 = ioc.Get<ICar>(new Type[] { typeof(IEngine) }, new object[] { new V12Engine() });
            //car2.ShowCarInfo(); 
            #endregion

            #region 单例创建实例
            //// 绑定 IPlanet(行星)接口和 Earth(地球类) 
            //// 使用SetCreationMethod方法设置 创建为单例
            //ioc.Bind<IPlanet, Earth>().SetCreationMethod<IPlanet>(CreateObjectMode.Singleton);
            //var earth1 = ioc.Get<IPlanet>();
            //var earth2 = ioc.Get<IPlanet>();

            //Console.WriteLine(object.ReferenceEquals(earth1,earth2)); 
            #endregion

            Console.ReadKey();
        }
    }

    #region 1. 绑定接口与获取实例 演示类
    // 所在程序集：Example
    // 类型完整名称：Example.IFly
    public interface IFly
    {
        void ICanFly();
    }

    // 所在程序集：Example
    // 类型完整名称：Example.Bird
    public class Bird : IFly
    {
        public void ICanFly()
        {
            Console.WriteLine($"我是{this.GetType().Name} 我能飞。"); ;
        }
    }
    #endregion

    #region 2. 构造函数注入 演示类
    public interface IEngine
    {
        string EngineName { get; }
    }

    public interface ICar
    {
        void ShowCarInfo();
    }

    public class V8Engine : IEngine
    {
        public string EngineName => "V8 发动机";
    }

    public class V12Engine : IEngine
    {
        public string EngineName => "V12 发动机";
    }

    public class AMGS63 : ICar
    {
        public IEngine Engine { get; }

        public AMGS63(IEngine engine)
        {
            Engine = engine;
        }

        public void ShowCarInfo()
        {
            Console.WriteLine($"车型{this.GetType().Name},使用{Engine.EngineName}");
        }
    }
    #endregion

    #region 3.单例创建实例 演示类
    public interface IPlanet
    {
        void ShowPlanetInf();
    }

    public class Earth : IPlanet
    {
        public void ShowPlanetInf()
        {
            Console.WriteLine("地球");
        }
    }
    #endregion
}
